package org.ravey.plugin;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;


public class PluginManager {
	
	int KernelVersion;
	IPlugin[] Plugins;
	PluginManifestManager manifest;
	String AppName;
	
	public PluginManager(int KVersion, String ApplicationName) {

	//set the manager's internal kernel version to the provided.
	KernelVersion = KVersion;
	
	//set the application name
	AppName = ApplicationName;
	
	//we don't currently have any plugins
	Plugins = null;
	}
	
	
	/**
	 * Load all plugins that are listed in a plugins manifest document
	 * 
	 * @param ManifestPath the path to the plugin manifest file
	 * @throws FileNotFoundException
	 */
	public void LoadPlugins(String ManifestPath) throws FileNotFoundException {
		//create a file object from the provided path
		File manfile = new File(ManifestPath);
	
		//make sure that the provided path is a file and does exist
		if(!manfile.isFile())
			throw new FileNotFoundException(manfile.getAbsolutePath() + " is not a valid plugin manifest file");
		
		//attempt to load the provided path as plugin manifest
		PluginManifestManager manifest = new PluginManifestManager(AppName, manfile);
		
		//get a list of plugins to initialize
		try {
			ArrayList<PluginInfo> pi = manifest.GetPluginInfoList(false);
			
			if(pi == null)
				return;
			
			//create a new array to hold all of the plugins that have been loaded.
			Plugins = new IPlugin[pi.size()];
			
			//Load all of the JarFile paths into a URL array
			URL[] jarfiles = new URL[pi.size()];
			for(int i=0;i<(pi.size()-1);i++){
				
				jarfiles[i] = new URL(pi.get(i).GetJarPath());

			}
			//create a url loader
			URLClassLoader ucl = new URLClassLoader(jarfiles);
			
			//load each of the plugins into the array
			for(int i=0;i<(pi.size()-1);i++){
				
				//get the class for the plugin
				Class<?> c = ucl.loadClass(pi.get(i).GetMainClass());
				Plugins[i] = (IPlugin)c.getConstructor().newInstance();

			}			

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * Create a new plugins manifest at the given location
	 * @param Path
	 */
	public void CreateManifest(String Path){
		File f = new File(Path);
		manifest = new PluginManifestManager(AppName);
		manifest.SaveManifest(f);
		
	}
	
	public void InstallPlugin(PluginInfo p) {
		manifest.AddPlugin(p);
	}
	
	public void RemovePlugin(PluginInfo p){
		try {
			manifest.RemovePlugin(p);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void SetDisabled(PluginInfo p, boolean disabled){
		try {
			manifest.SetPluginDisabled(p, disabled);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
